package com.openlogic.logic.service.datasource.impl;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.cloud.CloudClient;
import org.noear.solon.core.handle.UploadedFile;

import com.mybatisflex.core.query.QueryWrapper;
import com.openlogic.common.core.constants.CacheConstant;
import com.openlogic.common.core.exception.logic.RuleException;
import com.openlogic.common.core.web.domain.model.LoginUser;
import com.openlogic.common.plugins.db.api.dto.BaseDataSourceParamDto;
import com.openlogic.common.plugins.db.api.utils.FileUploadUtils;
import com.openlogic.common.plugins.spi.enums.DbType;
import com.openlogic.common.security.utils.SecurityUtil;
import com.openlogic.datasource.api.entity.DataSourceEntity;
import com.openlogic.datasource.api.entity.table.Tables;
import com.openlogic.datasource.api.enums.DataCategory;
import com.openlogic.datasource.api.enums.DataStatus;
import com.openlogic.datasource.api.enums.SyncStatus;
import com.openlogic.datasource.api.event.DataCacheEvent;
import com.openlogic.datasource.api.event.DataCacheEventModel;
import com.openlogic.logic.async.AsyncTask;
import com.openlogic.logic.mapper.datasource.DataSourceMapper;
import com.openlogic.logic.service.datasource.ExcelDataSourceService;

/**
 * @ClassName: ExcelDataSourceServiceImpl
 * @Description: Excel数据源接口实现
 * @author weiyongpeng
 * @date 2024年11月25日 下午5:25:02
 */
@Component
public class ExcelDataSourceServiceImpl implements ExcelDataSourceService {

	@Inject("${openlogic.rule.excel.savepath}")
	private String excelLoadPath;

	@Inject
	private AsyncTask asyncTask;

	private DataCacheEvent dataCacheEvent = new DataCacheEvent();

	@Inject
	private DataSourceMapper dataSourceMapper;

	@Override
	public void createDataSource(String name, UploadedFile file) throws IllegalStateException, IOException {
		LoginUser loginUser = SecurityUtil.getLoginUser();
		// 1、解析Excel，并生产对应data,column
		if (file == null) {
			throw new RuleException("文件不可以为空");
		}
		String dbPath = parseExcel(file);
		// 2、创建DataSourceEntity
		DataSourceEntity dataSourceEntity = new DataSourceEntity();
		long id = CloudClient.id().generate();

		dataSourceEntity.setName(name.trim());
		dataSourceEntity.setDbType(DbType.EXCEL.getDb());
		dataSourceEntity.setStatus(DataStatus.ENABLE.getKey());
		dataSourceEntity.setIsSync(SyncStatus.NotSync.getKey());
		dataSourceEntity.setCreateBy(String.valueOf(loginUser.getUserid()));
		dataSourceEntity.setUpdateBy(String.valueOf(loginUser.getUserid()));
		dataSourceEntity.setId(String.valueOf(id));
		dataSourceEntity.setCategory(String.valueOf(DataCategory.EXCEL.getLevel()));
		dataSourceEntity.setExcelPath(dbPath);
		// 3、执行持久化
		dataSourceMapper.insert(dataSourceEntity);
		// 4、发布缓存数据源事件，提高查询效率
		dataCacheEvent.publishCacheEvent(new DataCacheEventModel(CacheConstant.METADATA_SOURCE_KEY));
		// 5、异步执行同步任务
		asyncTask.doTaskReadExcel(file, dbPath, dataSourceEntity);
	}

	@Override
	public void updateDataSource(String id, BaseDataSourceParamDto dataSourceParam, UploadedFile file)
			throws IllegalStateException, IOException {
		// 1、查询数据源
		DataSourceEntity dataSource = dataSourceMapper.selectOneById(id);
		if (dataSource == null) {
			throw new RuleException("数据源不存在");
		}
		// 检查数据源名称是否存在
		if (!dataSource.getName().trim().equals(dataSourceParam.getName()) && checkName(dataSourceParam.getName())) {
			throw new RuleException("数据源名称已存在");
		}
		// 删除旧的文件
		File oldFile = new File(dataSource.getExcelPath());
		if (oldFile.exists()) {
			oldFile.delete();
		}
		// 2、更换excel文件地址
		String dbPath = parseExcel(file);

		// 3、执行持久化
		dataSource.setExcelPath(dbPath);
		dataSource.setName(dataSourceParam.getName());
		dataSourceMapper.update(dataSource);

		// 4、发布缓存数据源事件，提高查询效率
		dataCacheEvent.publishCacheEvent(new DataCacheEventModel(CacheConstant.METADATA_SOURCE_KEY));

		// 5、异步执行同步任务
		asyncTask.doTaskReadExcel(file, dbPath, dataSource);

	}

	/**
	 * 描述：解析Excel
	 * 
	 * @Title: parseExcel
	 * @param file
	 * @return
	 * @throws IOException
	 * @author weiyongpeng
	 * @date 2024年11月26日 下午6:06:56
	 */
	private String parseExcel(UploadedFile file) throws IOException {
		// 1.1、得到上传的保存路径
		String savePath = excelLoadPath;
		// 1.2、创建目录
		FileUploadUtils.mkdir(savePath);
		String dbPath = "";

		// 1.3、得到上传的原文件名
		String originalFilename = file.getName();
		String suffix = FileUploadUtils.getFileSuffix(originalFilename);
		String filename = FileUploadUtils.getTimeFilename() + suffix;
		dbPath += filename;
		// 1.4、保存
		file.transferTo(new File(savePath, filename));
		dbPath = savePath + "\\" + dbPath;
		return dbPath;
	}

	private boolean checkName(String name) {
		List<DataSourceEntity> queryDataSource = dataSourceMapper
				.selectListByQuery(QueryWrapper.create().where(Tables.dataSource.name.eq(name.trim())));
		return queryDataSource != null && !queryDataSource.isEmpty();
	}

}
